package xlog

import (
	"fmt"
	"runtime"
	"strings"
	"time"
)

// 记录日志信息[会将err进行原样返回出去]
//
//	inf		日志等级
//	file	错误文件
//	line	错误行号
//	msg		消息备注
//	err		错误详情
//	reflex	是否需要反射，即是否需要在此处注入runtime.Caller(2)进行获取
func saveLog(inf byte, file string, line uint, msg string, err error, reflex bool) error {
	defer func() {
		// 异常恢复逻辑
		if err := recover(); err != nil {
			fmt.Println("xlog日志记录出现异常：", err)
		}
	}()
	logs := LogStruct{
		Type:      string(inf),
		File:      file,
		Line:      line,
		Msg:       msg,
		CreatedAt: time.Now().Format(time.DateTime),
	}
	if err != nil {
		logs.Content = err.Error()
	}
	if logs.File == "" && logs.Line == 0 && reflex {
		_, temp_file, temp_line, _ := runtime.Caller(2)
		logs.File = temp_file
		logs.Line = uint(temp_line)
	}
	logs.File = file_replaces(logs.File)
	if _default.Console {
		fmt.Printf("[%s] %s:%d %s %s\t%s\n", logs.Type, logs.File, logs.Line, logs.Msg, logs.Content, time.Now().Format(time.DateTime))
	}
	if _default.SaveInterface != nil {
		_default.SaveInterface.Log(&logs)
		return err
	}
	return err
}

// 记录日志信息[对外函数，用于记录任意类型/等级的日志信息]
//
//	inf		日志等级
//	file	错误文件
//	line	错误行号
//	msg		消息备注
//	err		错误详情
func SaveAny(inf byte, file string, line uint, msg string, err error) {
	saveLog(inf, file, line, msg, err, false)
}

// 记录日志信息[对外函数，用于记录任意类型/等级的日志信息]
//
//	inf		日志等级
//	file	错误文件
//	line	错误行号
//	msg		消息备注
//	err		错误详情
func SaveAnyError(inf byte, file string, line uint, msg string, err error) error {
	return saveLog(inf, file, line, msg, err, false)
}

// 目录中的家目录去除
//
//	file_path	待替换的目录路径
func file_replaces(file_path string) string {
	// 目录分割符替换
	file_path = strings.ReplaceAll(file_path, "\\", "/")
	// 依赖路径替换
	if strings.Contains(file_path, "@") {
		temp := strings.Split(file_path, "@")
		temp_path := strings.Split(temp[0], "/")
		file_path = "pkg:" + temp_path[len(temp_path)-1] + "@" + temp[1]
	} else if strings.Contains(file_path, "/home") {
		temp := strings.Split(file_path, "/home")
		temp1 := strings.Split(temp[1], "/")
		file_path = "~/" + strings.Join(temp1[1:], "/")
	} else if strings.Contains(file_path, "/Users") {
		temp := strings.Split(file_path, "/Users")
		temp1 := strings.Split(temp[1], "/")
		file_path = "~/" + strings.Join(temp1[1:], "/")
	} else {
		file_path = strings.Replace(file_path, "/root", "~", 1)
	}
	return file_path
}

func Replates(pth string) string {
	return file_replaces(pth)
}
